package com.example.fashionshoes.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.fashionshoes.constant.JwtConst;
import com.example.fashionshoes.exception.BusinessException;
import com.example.fashionshoes.mapper.CouponMapper;
import com.example.fashionshoes.pojo.po.Coupon;
import com.example.fashionshoes.pojo.po.Goods;
import com.example.fashionshoes.pojo.po.UserCoupon;
import com.example.fashionshoes.pojo.vo.CouponVO;
import com.example.fashionshoes.service.CouponService;
import com.example.fashionshoes.service.GoodsService;
import com.example.fashionshoes.utils.ThreadLocalUtil;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper, Coupon> implements CouponService {
    @Resource
    private CouponMapper couponMapper;
    @Resource
    private UserCouponService userCouponService;
    @Resource
    private GoodsService goodsService;

    /**
     * 获取要售出的优惠劵
     *
     * @return 售出的优惠劵
     */
    @Override
    public CouponVO getCoupon() {
        //库存大于0，时间大于等于现在时间
        List<Coupon> secKillCoupon = couponMapper.getCoupon();
        List<Coupon> commonCoupon = lambdaQuery().ne(Coupon::getPrice, 0).list();
        return CouponVO.builder()
                .commonCoupon(commonCoupon)
                .secKillCoupon(secKillCoupon)
                .build();
    }

    /**
     * 优惠劵秒杀
     *
     * @param id 秒杀优惠劵id
     * @return 购买结果
     */
    @Override
    @Transactional
    public Boolean payCoupon(Integer id) throws BusinessException {
        if (id==null){
            return false;
        }
        Coupon coupon = lambdaQuery().eq(Coupon::getId, id).one();
        //优惠劵是否过期
        if (coupon.getEndTime().isBefore(LocalDateTime.now())) {
            throw new BusinessException("该优惠劵已过期");
        }
        //优惠劵是否库存充足
        if (coupon.getRemaining() <= 0) {
            throw new BusinessException("已售罄");
        }
        //是否开始秒杀
        if (!coupon.getStartTime().plusSeconds(coupon.getDuration()).isAfter(LocalDateTime.now())) {
            throw new BusinessException("未开始");
        }
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get(JwtConst.USER_ID);
        //是否为限购
        if (coupon.getPerLimit() == 1) {
            //判断user_coupon表是否存在
            List<UserCoupon> userCouponList = userCouponService.lambdaQuery().eq(UserCoupon::getUserId, userId).eq(UserCoupon::getCouponId, id).list();
            if (!userCouponList.isEmpty()) {
                throw new BusinessException("你已购买该优惠劵");
            }
        }
        //是否会vip专属
        //乐观锁-版本控制(使用remaining作为版本)
        //减少库存
        boolean update = lambdaUpdate().eq(Coupon::getId, id).eq(Coupon::getRemaining, coupon.getRemaining()).setSql("remaining = remaining -1").update();
        if (!update) {
            throw new BusinessException("当前人数过多，请稍后尝试！");
        }
        //向user_coupon插入数据
        Snowflake snowflake = IdUtil.getSnowflake(1,1);
        UserCoupon userCoupon = UserCoupon.builder()
                .id(null)
                .couponId(id)
                .userId(userId)
                .orderNumber(snowflake.nextIdStr())
                .getType(1)
                .getTime(LocalDateTime.now())
                .build();
        return userCouponService.save(userCoupon);
    }

    /**
     * 获取可用的优惠劵
     * @return 优惠劵集合
     */
    @Override
    public List<Coupon> getLimitCoupon(Integer goodsId) {
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer userId = (Integer) map.get(JwtConst.USER_ID);
        List<Coupon> couponList = userCouponService.getLimitCoupon(userId, goodsId);
        List<Coupon> coupons = new ArrayList<>();
        for (Coupon coupon : couponList) {
            if (coupon.getUseType().equals(0)) {
                //通用卷
                coupons.add(coupon);
            } else if (coupon.getUseType().equals(1)) {
                //指定分类
                Goods goods = goodsService.getById(goodsId);
                if (goods.getCategoryId().equals(coupon.getRelateId())) {
                    coupons.add(coupon);
                }
            }else {
                //指定商品
                if (coupon.getRelateId().equals(goodsId)) {
                    coupons.add(coupon);
                }
            }
        }
        return coupons;
    }
}
